home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / python2.4 / site-packages / impacket / dcerpc / dcerpc.py < prev    next >
Text File  |  2006-05-23  |  33KB  |  915 lines

  1. # Copyright (c) 2003-2006 CORE Security Technologies
  2. #
  3. # This software is provided under under a slightly modified version
  4. # of the Apache Software License. See the accompanying LICENSE file
  5. # for more information.
  6. #
  7. # $Id: dcerpc.py,v 1.7 2006/05/23 22:26:51 gera Exp $
  8. #
  9.  
  10. import array
  11. from binascii import crc32
  12. try:
  13.     from Crypto.Cipher import ARC4
  14.     from Crypto.Hash import MD4
  15.     POW = None
  16. except Exception:
  17.     try:
  18.         import POW
  19.     except Exception:
  20.         print "WARNING: Crypto package not found. Some features will fail."
  21.  
  22. from impacket import ntlm
  23. from impacket import ImpactPacket
  24. from impacket.structure import Structure,pack,unpack
  25.  
  26. # MS/RPC Constants
  27. MSRPC_REQUEST   = 0x00
  28. MSRPC_RESPONSE  = 0x02
  29. MSRPC_FAULT     = 0x03
  30. MSRPC_ACK       = 0x07
  31. MSRPC_BIND      = 0x0B
  32. MSRPC_BINDACK   = 0x0C
  33. MSRPC_BINDNAK   = 0x0D
  34. MSRPC_ALTERCTX  = 0x0E
  35. MSRPC_AUTH3     = 0x10
  36.  
  37. # MS/RPC Packet Flags
  38. MSRPC_FIRSTFRAG = 0x01
  39. MSRPC_LASTFRAG  = 0x02
  40. MSRPC_NOTAFRAG  = 0x04
  41. MSRPC_RECRESPOND= 0x08
  42. MSRPC_NOMULTIPLEX = 0x10
  43. MSRPC_NOTFORIDEMP = 0x20
  44. MSRPC_NOTFORBCAST = 0x40
  45. MSRPC_NOUUID    = 0x80
  46.  
  47.  
  48. #Reasons for rejection of a context element, included in bind_ack result reason
  49. rpc_provider_reason = {
  50.     0       : 'reason_not_specified',
  51.     1       : 'abstract_syntax_not_supported',
  52.     2       : 'proposed_transfer_syntaxes_not_supported',
  53.     3       : 'local_limit_exceeded'
  54. }
  55.  
  56. MSRPC_CONT_RESULT_ACCEPT = 0
  57. MSRPC_CONT_RESULT_USER_REJECT = 1
  58. MSRPC_CONT_RESULT_PROV_REJECT = 2
  59.  
  60. #Results of a presentation context negotiation
  61. rpc_cont_def_result = {
  62.     0       : 'acceptance',
  63.     1       : 'user_rejection',
  64.     2       : 'provider_rejection'
  65. }
  66.  
  67. #status codes, references:
  68. #http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rpc/rpc/rpc_return_values.asp
  69. #http://msdn.microsoft.com/library/default.asp?url=/library/en-us/randz/protocol/common_return_values.asp
  70. #winerror.h
  71. #http://www.opengroup.org/onlinepubs/9629399/apdxn.htm
  72.  
  73. rpc_status_codes = {
  74.     0x00000005L : 'rpc_s_access_denied',
  75.     0x00000008L : 'Authentication type not recognized',
  76.     0x000006C6L : 'rpc_x_invalid_bound',                # the arrays bound are invalid
  77.     0x000006F7L : 'rpc_x_bad_stub_data',                # the stub data is invalid, doesn't match with the IDL definition
  78.     0x1C010001L : 'nca_s_comm_failure',                 # unable to get response from server:
  79.     0x1C010002L : 'nca_s_op_rng_error',                 # bad operation number in call
  80.     0x1C010003L : 'nca_s_unk_if',                       # unknown interface
  81.     0x1C010006L : 'nca_s_wrong_boot_time',              # client passed server wrong server boot time
  82.     0x1C010009L : 'nca_s_you_crashed',                  # a restarted server called back a client
  83.     0x1C01000BL : 'nca_s_proto_error',                  # someone messed up the protocol
  84.     0x1C010013L : 'nca_s_out_args_too_big ',            # output args too big
  85.     0x1C010014L : 'nca_s_server_too_busy',              # server is too busy to handle call
  86.     0x1C010015L : 'nca_s_fault_string_too_long',        # string argument longer than declared max len
  87.     0x1C010017L : 'nca_s_unsupported_type ',            # no implementation of generic operation for object
  88.     0x1C000001L : 'nca_s_fault_int_div_by_zero',
  89.     0x1C000002L : 'nca_s_fault_addr_error ',
  90.     0x1C000003L : 'nca_s_fault_fp_div_zero',
  91.     0x1C000004L : 'nca_s_fault_fp_underflow',
  92.     0x1C000005L : 'nca_s_fault_fp_overflow',
  93.     0x1C000006L : 'nca_s_fault_invalid_tag',
  94.     0x1C000007L : 'nca_s_fault_invalid_bound ',
  95.     0x1C000008L : 'nca_s_rpc_version_mismatch',
  96.     0x1C000009L : 'nca_s_unspec_reject ',
  97.     0x1C00000AL : 'nca_s_bad_actid',
  98.     0x1C00000BL : 'nca_s_who_are_you_failed',
  99.     0x1C00000CL : 'nca_s_manager_not_entered ',
  100.     0x1C00000DL : 'nca_s_fault_cancel',
  101.     0x1C00000EL : 'nca_s_fault_ill_inst',
  102.     0x1C00000FL : 'nca_s_fault_fp_error',
  103.     0x1C000010L : 'nca_s_fault_int_overflow',
  104.     0x1C000012L : 'nca_s_fault_unspec',
  105.     0x1C000013L : 'nca_s_fault_remote_comm_failure ',
  106.     0x1C000014L : 'nca_s_fault_pipe_empty ',
  107.     0x1C000015L : 'nca_s_fault_pipe_closed',
  108.     0x1C000016L : 'nca_s_fault_pipe_order ',
  109.     0x1C000017L : 'nca_s_fault_pipe_discipline',
  110.     0x1C000018L : 'nca_s_fault_pipe_comm_error',
  111.     0x1C000019L : 'nca_s_fault_pipe_memory',
  112.     0x1C00001AL : 'nca_s_fault_context_mismatch ',
  113.     0x1C00001BL : 'nca_s_fault_remote_no_memory ',
  114.     0x1C00001CL : 'nca_s_invalid_pres_context_id',
  115.     0x1C00001DL : 'nca_s_unsupported_authn_level',
  116.     0x1C00001FL : 'nca_s_invalid_checksum ',
  117.     0x1C000020L : 'nca_s_invalid_crc',
  118.     0x1C000021L : 'nca_s_fault_user_defined',
  119.     0x1C000022L : 'nca_s_fault_tx_open_failed',
  120.     0x1C000023L : 'nca_s_fault_codeset_conv_error',
  121.     0x1C000024L : 'nca_s_fault_object_not_found ',
  122.     0x1C000025L : 'nca_s_fault_no_client_stub'
  123. }
  124.  
  125. class MSRPCArray:
  126.     def __init__(self, id=0, len=0, size=0):
  127.         self._length = len
  128.         self._size = size
  129.         self._id = id
  130.         self._max_len = 0
  131.         self._offset = 0
  132.         self._length2 = 0
  133.         self._name = ''
  134.  
  135.     def set_max_len(self, n):
  136.         self._max_len = n
  137.     def set_offset(self, n):
  138.         self._offset = n
  139.     def set_length2(self, n):
  140.         self._length2 = n
  141.     def get_size(self):
  142.         return self._size
  143.     def set_name(self, n):
  144.         self._name = n
  145.     def get_name(self):
  146.         return self._name
  147.     def get_id(self):
  148.         return self._id
  149.     def rawData(self):
  150.         return pack('<HHLLLL', self._length, self._size, 0x12345678, self._max_len, self._offset, self._length2) + self._name.encode('utf-16le')
  151.  
  152. class MSRPCNameArray:
  153.     def __init__(self, data = None):
  154.         self._count = 0
  155.         self._max_count = 0
  156.         self._elements = []
  157.  
  158.         if data: self.load(data)
  159.  
  160.     def load(self, data):
  161.         ptr = unpack('<L', data[:4])[0]
  162.         index = 4
  163.         if 0 == ptr: # No data. May be a bug in certain versions of Samba.
  164.             return
  165.  
  166.         self._count, _, self._max_count = unpack('<LLL', data[index:index+12])
  167.         index += 12
  168.  
  169.         # Read each object's header.
  170.         for i in range(0, self._count):
  171.             aindex, length, size, _ = unpack('<LHHL', data[index:index+12])
  172.             self._elements.append(MSRPCArray(aindex, length, size))
  173.             index += 12
  174.  
  175.         # Read the objects themselves.
  176.         for element in self._elements:
  177.             max_len, offset, curlen = unpack('<LLL', data[index:index+12])
  178.             index += 12
  179.             element.set_name(unicode(data[index:index+2*curlen], 'utf-16le'))
  180.             element.set_max_len(max_len)
  181.             element.set_offset(offset)
  182.             element.set_length2(curlen)
  183.             index += 2*curlen
  184.             if curlen & 0x1: index += 2 # Skip padding.
  185.  
  186.     def elements(self):
  187.         return self._elements
  188.  
  189.     def rawData(self):
  190.         ret = pack('<LLLL', 0x74747474, self._count, 0x47474747, self._max_count)
  191.         pos_ret = []
  192.         for i in xrange(0, self._count):
  193.             ret += pack('<L', self._elements[i].get_id())
  194.             data = self._elements[i].rawData()
  195.             ret += data[:8]
  196.             pos_ret += data[8:]
  197.  
  198.         return ret + pos_ret
  199.  
  200. class MSRPCHeader(ImpactPacket.Header):
  201.     _SIZE = 16
  202.     commonHdr = ( # not used, just for doc and future use
  203.         ('ver_major','B'),                              # 0
  204.         ('ver_minor','B'),                              # 1
  205.         ('type','B=MSRPC_REQUEST'),                     # 2
  206.         ('flags','B=MSRPC_FIRSTFRAG | MSRPC_LASTFRAG'), # 3
  207.         ('represntation','<L=0x10'),                    # 4
  208.         ('frag_len','<H=24+len(data)+len(auth_data)'),  # 8
  209.         ('auth_len','<H=len(auth_data)-8'),             # 10
  210.         ('call_id','<L=1'),                             # 12    <-- Common up to here (including this)
  211.     )
  212.  
  213.     structure = ( # not used, just for documentation and future use
  214.         ('data',':'),                                   # 24
  215.         ('auth_data',':'),
  216.     )
  217.  
  218.     def __init__(self, aBuffer = None, endianness = '<'):
  219.         ImpactPacket.Header.__init__(self, self._SIZE)
  220.  
  221.         self.endianness = endianness
  222.         self.set_version((5, 0))
  223.         self.set_flags(MSRPC_FIRSTFRAG | MSRPC_LASTFRAG)
  224.         if endianness == '<':
  225.             self.set_representation(0x10)
  226.         else:
  227.             self.set_representation(0x0)
  228.         self.__frag_len_set = 0
  229.         self.set_auth_len(0)
  230.         self.set_call_id(1)
  231.         self.set_auth_data('')
  232.  
  233.         if aBuffer: self.load_header(aBuffer)
  234.  
  235.     def get_version(self):
  236.         """ This method returns a tuple in (major, minor) form."""
  237.         return (self.get_byte(0), self.get_byte(1))
  238.     def set_version(self, version):
  239.         """ This method takes a tuple in (major, minor) form."""
  240.         self.set_byte(0, version[0])
  241.         self.set_byte(1, version[1])
  242.  
  243.     def get_type(self):
  244.         return self.get_byte(2)
  245.     def set_type(self, type):
  246.         self.set_byte(2, type)
  247.  
  248.     def get_flags(self):
  249.         return self.get_byte(3)
  250.     def set_flags(self, flags):
  251.         self.set_byte(3, flags)
  252.  
  253.     def get_representation(self):
  254.         return self.get_long(4, self.endianness)
  255.     def set_representation(self, representation):
  256.         self.set_long(4, representation, self.endianness)
  257.  
  258.     def get_frag_len(self):
  259.         return self.get_word(8, self.endianness)
  260.     def set_frag_len(self, len):
  261.         self.__frag_len_set == 1
  262.         self.set_word(8, len, self.endianness)
  263.  
  264.     def get_auth_len(self):
  265.         return self.get_word(10, self.endianness)
  266.     def set_auth_len(self, len):
  267.         self.set_word(10, len, self.endianness)
  268.     def set_auth_data(self, data):
  269.         self._auth_data = data
  270.  
  271.     def get_call_id(self):
  272.         return self.get_long(12, self.endianness)
  273.     def set_call_id(self, id):
  274.         self.set_long(12, id, self.endianness)
  275.  
  276.     def get_header_size(self):
  277.         return self._SIZE
  278.  
  279.     def contains(self, aHeader):
  280.         ImpactPacket.Header.contains(self, aHeader)
  281.         if self.child():
  282.             self.set_op_num(self.child().OP_NUM)
  283.  
  284.     def set_alloc_hint(self, hint):
  285.         pass
  286.  
  287.     def get_packet(self):
  288.         if self._auth_data:
  289.             self.set_auth_len(len(self._auth_data)-8)
  290.  
  291.         if self.child():
  292.             contents_size = self.child().get_size()
  293.         else:
  294.             contents_size = 0
  295.  
  296.         contents_size += len(self._auth_data)
  297.         if not self.__frag_len_set:
  298.             self.set_frag_len(self.get_header_size() + contents_size)
  299.         self.set_alloc_hint(contents_size)
  300.         return ImpactPacket.Header.get_packet(self)+self._auth_data
  301.  
  302. class MSRPCRequestHeader(MSRPCHeader):
  303.     _SIZE = 24
  304.  
  305.     structure = (  # not used, just for documentation and future use
  306.         ('alloc_hint','<L=frag_len'),                   # 16
  307.         ('ctx_id','<H=0'),                              # 20
  308.         ('op_num','<H'),                                # 22
  309.         ('data',':'),                                   # 24
  310.         ('auth_data',':'),
  311.     )
  312.  
  313.     def __init__(self, aBuffer = None, endianness = '<'):
  314.         MSRPCHeader.__init__(self, aBuffer = aBuffer, endianness = endianness)
  315.         self.set_type(MSRPC_REQUEST)
  316.         self.set_ctx_id(0)
  317.         self.set_alloc_hint(0)
  318.  
  319.     def get_alloc_hint(self):
  320.         return self.get_long(16, self.endianness)
  321.     def set_alloc_hint(self, len):
  322.         self.set_long(16, len, self.endianness)
  323.  
  324.     def get_ctx_id(self):
  325.         return self.get_word(20, self.endianness)
  326.     def set_ctx_id(self, id):
  327.         self.set_word(20, id, self.endianness)
  328.  
  329.     def get_op_num(self):
  330.         return self.get_word(22, self.endianness)
  331.     def set_op_num(self, op):
  332.         self.set_word(22, op, self.endianness)
  333.  
  334. class MSRPCRespHeader(MSRPCHeader):
  335.     _SIZE = 24
  336.  
  337.     structure = ( # not used, just for documentation and future use
  338.         ('alloc_hint','<L=frag_len'),                   # 16    <-- Common up to here (including this)
  339.         ('ctx_id','<H=0'),                              # 20
  340.         ('cancel_count','<B'),                          # 22
  341.         ('padding','<B=0'),                             # 23
  342.         ('data',':'),                                   # 24
  343.         ('auth_data',':'),
  344.     )
  345.  
  346.     def __init__(self, aBuffer = None, endianness = '<'):
  347.         MSRPCHeader.__init__(self, aBuffer = aBuffer, endianness = endianness)
  348.         self.set_type(MSRPC_RESPONSE)
  349.         self.set_ctx_id(0)
  350.         self.set_alloc_hint(0)
  351.  
  352.     def get_alloc_hint(self):
  353.         return self.get_long(16, self.endianness)
  354.     def set_alloc_hint(self, len):
  355.         self.set_long(16, len, self.endianness)
  356.  
  357.     def get_ctx_id(self):
  358.         return self.get_word(20, self.endianness)
  359.     def set_ctx_id(self, id):
  360.         self.set_word(20, id, self.endianness)
  361.  
  362.     def get_cancel_count(self):
  363.         return self.get_byte(22)
  364.  
  365. class MSRPCBind(MSRPCHeader):
  366.     _SIZE = 72-44
  367.  
  368.     structure = ( # not used, just for documentation and future use
  369.         ('max_tfrag','<H=4280'),
  370.         ('max_rfrag','<H=4280'),
  371.         ('assoc_group','<L=0'),
  372.         ('ctx_num','B'),
  373.     )
  374.  
  375.     def __init__(self, aBuffer = None, endianness = '<'):
  376.         MSRPCHeader.__init__(self, aBuffer = aBuffer, endianness = endianness)
  377.  
  378.         self.set_type(MSRPC_BIND)
  379.         self.set_max_tfrag(4280)
  380.         self.set_max_rfrag(4280)
  381.         self.set_assoc_group(0)
  382.         self.set_ctx_num(1)
  383.  
  384.     def get_max_tfrag(self):
  385.         return self.get_word(16, self.endianness)
  386.     def set_max_tfrag(self, size):
  387.         self.set_word(16, size, self.endianness)
  388.  
  389.     def get_max_rfrag(self):
  390.         return self.get_word(18, self.endianness)
  391.     def set_max_rfrag(self, size):
  392.         self.set_word(18, size, self.endianness)
  393.  
  394.     def get_assoc_group(self):
  395.         return self.get_long(20, self.endianness)
  396.     def set_assoc_group(self, id):
  397.         self.set_long(20, id, self.endianness)
  398.  
  399.     def get_ctx_num(self):
  400.         return self.get_byte(24)
  401.     def set_ctx_num(self, num):
  402.         self._SIZE = 28+num*44
  403.         self.set_byte(24, num)
  404.  
  405.     # --- next fields repeated for each interface to bind to
  406.     def get_ctx_id(self, index = 0):
  407.         return self.get_word(28+44*index, self.endianness)
  408.     def set_ctx_id(self, id, index = 0):
  409.         self.set_word(28+44*index, id, self.endianness)
  410.  
  411.     def get_trans_num(self, index = 0):
  412.         return self.get_byte(30+44*index)
  413.     def set_trans_num(self, op, index = 0):
  414.         self.set_byte(30+44*index, op)
  415.         self.set_byte(31+44*index, 0)
  416.  
  417.     def get_if_binuuid(self, index = 0):
  418.         return self.get_bytes().tolist()[32+44*index:32+44*index+16]
  419.     def set_if_binuuid(self, binuuid, index = 0):
  420.         self.get_bytes()[32+44*index:32+len(binuuid)+44*index] = array.array('B', binuuid)
  421.  
  422.     def set_if_ver(self,ver,minor, index = 0):
  423.         self.set_word(48+44*index, ver, self.endianness)
  424.         self.set_word(50+44*index, minor, self.endianness)
  425.     def get_if_ver(self, index = 0):
  426.         return self.get_word(48+44*index, self.endianness)
  427.     def get_if_ver_minor(self, index = 0):
  428.         return self.get_word(50+44*index, self.endianness)
  429.         
  430.     def get_xfer_syntax_binuuid(self, index = 0):
  431.         return self.get_bytes().tolist()[52+44*index:52+44*index+16]
  432.     def set_xfer_syntax_binuuid(self, binuuid, index = 0):
  433.         self.get_bytes()[52+44*index:52+len(binuuid)+44*index] = array.array('B', binuuid)
  434.     
  435.     def set_xfer_syntax_ver(self,ver, index = 0):
  436.         self.set_long(68+44*index, ver, self.endianness)
  437.     def get_xfer_syntax_ver(self, index = 0):
  438.         self.get_long(68+44*index, ver, self.endianness)
  439.         
  440. class MSRPCBindAck(ImpactPacket.Header):
  441.     _SIZE = 56
  442.  
  443.     def __init__(self, aBuffer = None):
  444.         ImpactPacket.Header.__init__(self, self._SIZE)
  445.  
  446.         self.set_type(MSRPC_BINDACK)
  447.  
  448.         if aBuffer: self.load_header(aBuffer)
  449.  
  450.     def get_version(self):
  451.         """ This method returns a tuple in (major, minor) form."""
  452.         return (self.get_byte(0), self.get_byte(1))
  453.     def set_version(self, version):
  454.         """ This method takes a tuple in (major, minor) form."""
  455.         self.set_byte(0, version[0])
  456.         self.set_byte(1, version[1])
  457.  
  458.     def get_type(self):
  459.         return self.get_byte(2)
  460.     def set_type(self, type):
  461.         self.set_byte(2, type)
  462.  
  463.     def get_flags(self):
  464.         return self.get_byte(3)
  465.     def set_flags(self, flags):
  466.         self.set_byte(3, flags)
  467.  
  468.     def get_representation(self):
  469.         return self.get_long(4, '<')
  470.     def set_representation(self, representation):
  471.         self.set_long(4, representation, '<')
  472.  
  473.     def get_frag_len(self):
  474.         return self.get_word(8, '<')
  475.     def set_frag_len(self, len):
  476.         self.set_word(8, len, '<')
  477.  
  478.     def get_auth_len(self):
  479.         return self.get_word(10, '<')
  480.     def set_auth_len(self, len):
  481.         self.set_word(10, len, '<')
  482.     def get_auth_data(self):
  483.         data = self.get_bytes()
  484.         return data[-self.get_auth_len()-8:]
  485.  
  486.     def get_call_id(self):
  487.         return self.get_long(12, '<')
  488.     def set_call_id(self, id):
  489.         self.set_long(12, id, '<')
  490.  
  491.     def get_max_tfrag(self):
  492.         return self.get_word(16, '<')
  493.     def set_max_tfrag(self, size):
  494.         self.set_word(16, size, '<')
  495.  
  496.     def get_max_rfrag(self):
  497.         return self.get_word(18, '<')
  498.     def set_max_rfrag(self, size):
  499.         self.set_word(18, size, '<')
  500.  
  501.     def get_assoc_group(self):
  502.         return self.get_long(20, '<')
  503.     def set_assoc_group(self, id):
  504.         self.set_long(20, id, '<')
  505.  
  506.     def get_secondary_addr_len(self):
  507.         return self.get_word(24, '<')
  508.     def set_secondary_addr_len(self, len):
  509.         self.set_word(24, len, '<')
  510.  
  511.     def get_secondary_addr(self):
  512.         return self.get_bytes().tolist()[26:26+self.get_secondary_addr_len()]
  513.     def set_secondary_addr(self, addr):
  514.         self.get_bytes()[26:26+self.get_secondary_addr_len()] = array.array('B', addr)
  515.         self.set_secondary_addr_len(len(addr))
  516.  
  517.     def _get_results_offset(self):
  518.         answer = 26+self.get_secondary_addr_len()
  519.         answer +=3
  520.         answer -= answer % 4
  521.         return answer+2
  522.     
  523.     def get_results_num(self):
  524.         return self.get_byte(self._get_results_offset()-2)
  525.     def set_results_num(self, num):
  526.         self.set_byte(self._get_results_offset()-2, num)
  527.  
  528.     def get_result(self, index = 0):
  529.         return self.get_word(self._get_results_offset()+2*index, '<' )
  530.     def set_result(self, res, index = 0):
  531.         self.set_word(self._get_results_offset()+2*index, '<' )
  532.  
  533.     def get_xfer_syntax_binuuid(self):
  534.         return self.get_bytes().tolist()[-20:]
  535.     def set_xfer_syntax_binuuid(self, binuuid):
  536.         assert 20 == len(binuuid)
  537.         self.get_bytes()[-20:] = array.array('B', binuuid)
  538.  
  539.  
  540.     def get_header_size(self):
  541.         var_size = len(self.get_bytes()) - self._SIZE
  542.         # assert var_size > 0
  543.         return self._SIZE + var_size
  544.  
  545.     def contains(self, aHeader):
  546.         ImpactPacket.Header.contains(self, aHeader)
  547.         if self.child():
  548.             contents_size = self.child().get_size()
  549.             self.set_op_num(self.child().OP_NUM)
  550.             self.set_frag_len(self.get_header_size() + contents_size)
  551.             self.set_alloc_hint(contents_size)
  552.  
  553. class MSRPCBindNak(ImpactPacket.Header):
  554.     _SIZE = 24
  555.  
  556.     def __init__(self, aBuffer = None):
  557.         ImpactPacket.Header.__init__(self, self._SIZE)
  558.  
  559.         self.set_type(MSRPC_BINDNAK)
  560.  
  561.         if aBuffer: self.load_header(aBuffer)
  562.  
  563.     def get_version(self):
  564.         """ This method returns a tuple in (major, minor) form."""
  565.         return (self.get_byte(0), self.get_byte(1))
  566.     def set_version(self, version):
  567.         """ This method takes a tuple in (major, minor) form."""
  568.         self.set_byte(0, version[0])
  569.         self.set_byte(1, version[1])
  570.  
  571.     def get_type(self):
  572.         return self.get_byte(2)
  573.     def set_type(self, type):
  574.         self.set_byte(2, type)
  575.  
  576.     def get_flags(self):
  577.         return self.get_byte(3)
  578.     def set_flags(self, flags):
  579.         self.set_byte(3, flags)
  580.  
  581.     def get_representation(self):
  582.         return self.get_long(4, '<')
  583.     def set_representation(self, representation):
  584.         self.set_long(4, representation, '<')
  585.  
  586.     def get_frag_len(self):
  587.         return self.get_word(8, '<')
  588.     def set_frag_len(self, len):
  589.         self.set_word(8, len, '<')
  590.  
  591.     def get_auth_len(self):
  592.         return self.get_word(10, '<')
  593.     def set_auth_len(self, len):
  594.         self.set_word(10, len, '<')
  595.  
  596.     def get_call_id(self):
  597.         return self.get_long(12, '<')
  598.     def set_call_id(self, id):
  599.         self.set_long(12, id, '<')
  600.  
  601.     def get_reason(self):
  602.         return self.get_word(16, '<')
  603.     def set_reason(self, reason):
  604.         self.set_word(16, reason, '<')
  605.  
  606.     def get_assoc_group(self):
  607.         return self.get_long(20, '<')
  608.     def set_assoc_group(self, id):
  609.         self.set_long(20, id, '<')
  610.  
  611.  
  612.     def get_header_size(self):
  613.         return self._SIZE
  614.  
  615. class DCERPC:
  616.     _max_ctx = 0
  617.     def __init__(self,transport):
  618.         self._transport = transport
  619.         self.set_ctx_id(0)
  620.         self._max_frag = None
  621.         self.set_default_max_fragment_size()
  622.  
  623.     def set_ctx_id(self, ctx_id):
  624.         self._ctx = ctx_id
  625.  
  626.     def connect(self):
  627.         return self._transport.connect()
  628.  
  629.     def disconnect(self):
  630.         return self._transport.disconnect()
  631.  
  632.     def set_max_fragment_size(self, fragment_size):
  633.         # -1 is default fragment size: 0 for v5, 1300 y pico for v4
  634.         #  0 is don't fragment
  635.         #    other values are max fragment size
  636.         if fragment_size == -1:
  637.             self.set_default_max_fragment_size()
  638.         else:
  639.             self._max_frag = fragment_size
  640.  
  641.     def set_default_max_fragment_size(self):
  642.         # default is 0: don'fragment. v4 will override this method
  643.         self._max_frag = 0
  644.  
  645.     def send(self, data): raise RuntimeError, 'virtual method. Not implemented in subclass'
  646.     def recv(self): raise RuntimeError, 'virtual method. Not implemented in subclass'
  647.     def alter_ctx(self, newUID, bogus_binds = ''): raise RuntimeError, 'virtual method. Not implemented in subclass'
  648.     def set_credentials(self, username, password): pass
  649.     def set_auth_level(self, auth_level): pass
  650.     def get_idempotent(self): return 0
  651.     def set_idempotent(self, flag): pass
  652.     def call(self, function, body):
  653.         return self.send(DCERPC_RawCall(function, str(body)))
  654.  
  655. class DCERPC_v5(DCERPC):
  656.     endianness = '<'
  657.     def __init__(self, transport):
  658.         DCERPC.__init__(self, transport)
  659.         self.__auth_level = ntlm.NTLM_AUTH_NONE
  660.         self.__username = None
  661.         self.__password = None
  662.         
  663.     def set_auth_level(self, auth_level):
  664.         # auth level is ntlm.NTLM_AUTH_*
  665.         self.__auth_level = auth_level
  666.  
  667.     def set_credentials(self, username, password):
  668.         self.set_auth_level(ntlm.NTLM_AUTH_CONNECT)
  669.         # self.set_auth_level(ntlm.NTLM_AUTH_CALL)
  670.         # self.set_auth_level(ntlm.NTLM_AUTH_PKT_INTEGRITY)
  671.         # self.set_auth_level(ntlm.NTLM_AUTH_PKT_PRIVACY)
  672.         self.__username = username
  673.         self.__password = password
  674.  
  675.     def bind(self, uuid, alter = 0, bogus_binds = 0):
  676.         bind = MSRPCBind(endianness = self.endianness)
  677.  
  678.         syntax = '\x04\x5d\x88\x8a\xeb\x1c\xc9\x11\x9f\xe8\x08\x00\x2b\x10\x48\x60'
  679.  
  680.         if self.endianness == '>':
  681.             syntax = unpack('<LHHBB6s', syntax)
  682.             syntax = pack('>LHHBB6s', *syntax)
  683.  
  684.             uuid = list(unpack('<LHHBB6sHH', uuid))
  685.  
  686.             uuid[-1] ^= uuid[-2]
  687.             uuid[-2] ^= uuid[-1]
  688.             uuid[-1] ^= uuid[-2]
  689.             
  690.             uuid = pack('>LHHBB6sHH', *uuid)
  691.  
  692.         ctx = 0
  693.         for i in range(bogus_binds):
  694.             bind.set_ctx_id(self._ctx, index = ctx)
  695.             bind.set_trans_num(1, index = ctx)
  696.             bind.set_if_binuuid('A'*20, index = ctx)
  697.             bind.set_xfer_syntax_binuuid(syntax, index = ctx)
  698.             bind.set_xfer_syntax_ver(2, index = ctx)
  699.  
  700.             self._ctx += 1
  701.             ctx += 1
  702.  
  703.         bind.set_ctx_id(self._ctx, index = ctx)
  704.         bind.set_trans_num(1, index = ctx)
  705.         bind.set_if_binuuid(uuid,index = ctx)
  706.         bind.set_xfer_syntax_binuuid(syntax, index = ctx)
  707.         bind.set_xfer_syntax_ver(2, index = ctx)
  708.  
  709.         bind.set_ctx_num(ctx+1)
  710.  
  711.         if alter:
  712.             bind.set_type(MSRPC_ALTERCTX)
  713.  
  714.         if (self.__auth_level != ntlm.NTLM_AUTH_NONE):
  715.             if (self.__username is None) or (self.__password is None):
  716.                 self.__username, self.__password, nth, lmh = self._transport.get_credentials()
  717.             auth = ntlm.NTLMAuthNegotiate()
  718.             auth['auth_level']  = self.__auth_level
  719.             auth['auth_ctx_id'] = self._ctx + 79231 
  720.             bind.set_auth_data(str(auth))
  721.  
  722.         self._transport.send(bind.get_packet())
  723.  
  724.         s = self._transport.recv()
  725.         if s != 0:
  726.             resp = MSRPCBindAck(s)
  727.         else:
  728.             return 0 #mmm why not None?
  729.  
  730.         if resp.get_type() == MSRPC_BINDNAK:
  731.             resp = MSRPCBindNak(s)
  732.             status_code = resp.get_reason()
  733.             if rpc_status_codes.has_key(status_code):
  734.                 raise Exception(rpc_status_codes[status_code], resp)
  735.             else:
  736.                 raise Exception('Unknown DCE RPC fault status code: %.8x' % status_code, resp)
  737.             
  738.         self.__max_xmit_size = resp.get_max_tfrag()
  739.  
  740.         if self.__auth_level != ntlm.NTLM_AUTH_NONE:
  741.             authResp = ntlm.NTLMAuthChallenge(data = resp.get_auth_data().tostring())
  742.             self._ntlm_challenge = authResp['challenge']
  743.             response = ntlm.NTLMAuthChallengeResponse(self.__username,self.__password, self._ntlm_challenge)
  744.             response['auth_ctx_id'] = self._ctx + 79231 
  745.             response['auth_level'] = self.__auth_level
  746.  
  747.             if self.__auth_level in (ntlm.NTLM_AUTH_CONNECT, ntlm.NTLM_AUTH_PKT_INTEGRITY, ntlm.NTLM_AUTH_PKT_PRIVACY):
  748.                 if self.__password:
  749.                     key = ntlm.compute_nthash(self.__password)
  750.                     if POW:
  751.                         hash = POW.Digest(POW.MD4_DIGEST)
  752.                     else:
  753.                         hash = MD4.new()
  754.                     hash.update(key)
  755.                     key = hash.digest()
  756.                 else:
  757.                     key = '\x00'*16
  758.  
  759.             if POW:
  760.                 cipher = POW.Symmetric(POW.RC4)
  761.                 cipher.encryptInit(key)
  762.                 self.cipher_encrypt = cipher.update
  763.             else:
  764.                 cipher = ARC4.new(key)
  765.                 self.cipher_encrypt = cipher.encrypt
  766.  
  767.             if response['flags'] & ntlm.NTLMSSP_KEY_EXCHANGE:
  768.                 session_key = 'A'*16     # XXX Generate random session key
  769.                 response['session_key'] = self.cipher_encrypt(session_key)
  770.                 if POW:
  771.                     cipher = POW.Symmetric(POW.RC4)
  772.                     cipher.encryptInit(session_key)
  773.                     self.cipher_encrypt = cipher.update
  774.                 else:
  775.                     cipher = ARC4.new(session_key)
  776.                     self.cipher_encrypt = cipher.encrypt
  777.  
  778.             self.sequence = 0
  779.  
  780.             auth3 = MSRPCHeader()
  781.             auth3.set_type(MSRPC_AUTH3)
  782.             auth3.set_auth_data(str(response))
  783.             self._transport.send(auth3.get_packet(), forceWriteAndx = 1)
  784.  
  785.         return resp     # means packet is signed, if verifier is wrong it fails
  786.  
  787.     def _transport_send(self, rpc_packet, forceWriteAndx = 0, forceRecv = 0):
  788.         if self.__auth_level == ntlm.NTLM_AUTH_CALL:
  789.             if rpc_packet.get_type() == MSRPC_REQUEST:
  790.                 response = ntlm.NTLMAuthChallengeResponse(self.__username,self.__password, self._ntlm_challenge)
  791.                 response['auth_ctx_id'] = self._ctx + 79231 
  792.                 response['auth_level'] = self.__auth_level
  793.                 rpc_packet.set_auth_data(str(response))
  794.                 
  795.         if self.__auth_level in [ntlm.NTLM_AUTH_PKT_INTEGRITY, ntlm.NTLM_AUTH_PKT_PRIVACY]:
  796.             verifier = ntlm.NTLMAuthVerifier()
  797.             verifier['auth_level'] = self.__auth_level
  798.             verifier['auth_ctx_id'] = self._ctx + 79231 
  799.             verifier['data'] = ' '*12
  800.             rpc_packet.set_auth_data(str(verifier))
  801.  
  802.             rpc_call = rpc_packet.child()
  803.             if self.__auth_level == ntlm.NTLM_AUTH_PKT_PRIVACY:
  804.                 data = DCERPC_RawCall(rpc_call.OP_NUM)
  805.                 data.setData(self.cipher_encrypt(rpc_call.get_packet()))
  806.                 rpc_packet.contains(data)
  807.             
  808.             crc = crc32(rpc_call.get_packet())
  809.             data = pack('<LLL',0,crc,self.sequence)     # XXX 0 can be anything: randomize
  810.             data = self.cipher_encrypt(data)
  811.             verifier['data'] = data
  812.             rpc_packet.set_auth_data(str(verifier))
  813.  
  814.             self.sequence += 1
  815.  
  816.         self._transport.send(rpc_packet.get_packet(), forceWriteAndx = forceWriteAndx, forceRecv = forceRecv)
  817.  
  818.     def send(self, data):
  819.         # This endianness does necesary have to be the same as the one used in the bind
  820.         # however, the endianness of the stub data MUST be the same as the one in the bind
  821.         # i.e. the endianness on the next call could be hardcoded to any
  822.         rpc = MSRPCRequestHeader(endianness = self.endianness)
  823.  
  824.         rpc.set_ctx_id(self._ctx)
  825.  
  826.         max_frag = self._max_frag
  827.  
  828.         if data.get_size() > self.__max_xmit_size - 32:
  829.             max_frag = self.__max_xmit_size - 32    # XXX: 32 is a safe margin for auth data
  830.  
  831.         if self._max_frag:
  832.             max_frag = min(max_frag, self._max_frag)
  833.  
  834.         if max_frag:
  835.             packet = str(data.get_bytes().tostring())
  836.             offset = 0
  837.             rawcall = DCERPC_RawCall(data.OP_NUM)
  838.  
  839.             while 1:
  840.                 toSend = packet[offset:offset+max_frag]
  841.                 if not toSend:
  842.                     break
  843.                 flags = 0
  844.                 if offset == 0:
  845.                     flags |= MSRPC_FIRSTFRAG
  846.                 offset += len(toSend)
  847.                 if offset == len(packet):
  848.                     flags |= MSRPC_LASTFRAG
  849.                 rpc.set_flags(flags)
  850.  
  851.                 rawcall.setData(toSend)
  852.                 rpc.contains(rawcall)
  853.                 self._transport_send(rpc, forceWriteAndx = 1, forceRecv = flags & MSRPC_LASTFRAG)
  854.         else:
  855.             rpc.contains(data)
  856.             self._transport_send(rpc)
  857.  
  858.     def recv(self):
  859.         self.response_data = self._transport.recv()
  860.         self.response_header = MSRPCRespHeader(self.response_data)
  861.         off = self.response_header.get_header_size()
  862.         if self.response_header.get_type() == MSRPC_FAULT and self.response_header.get_frag_len() >= off+4:
  863.             status_code = unpack("<L",self.response_data[off:off+4])[0]
  864.             if rpc_status_codes.has_key(status_code):
  865.                 raise Exception(rpc_status_codes[status_code])
  866.             else:
  867.                 raise Exception('Unknown DCE RPC fault status code: %.8x' % status_code)
  868.         answer = self.response_data[off:]
  869.         auth_len = self.response_header.get_auth_len()
  870.         if auth_len:
  871.             auth_len += 8
  872.             auth_data = answer[-auth_len:]
  873.             ntlmssp   = ntlm.NTLMAuthHeader(data = auth_data)
  874.             answer = answer[:-auth_len]
  875.  
  876.             if ntlmssp['auth_level'] == ntlm.NTLM_AUTH_PKT_PRIVACY:
  877.                 answer = self.cipher_encrypt(answer)
  878.  
  879.             if ntlmssp['auth_pad_len']:
  880.                 answer = answer[:-ntlmssp['auth_pad_len']]
  881.  
  882.             if ntlmssp['auth_level'] in [ntlm.NTLM_AUTH_PKT_INTEGRITY, ntlm.NTLM_AUTH_PKT_PRIVACY]:
  883.                 ntlmssp = ntlm.NTLMAuthVerifier(data = auth_data)
  884.                 data = self.cipher_encrypt(ntlmssp['data'])
  885.                 zero, crc, sequence = unpack('<LLL', data)
  886.                 self.sequence = sequence + 1
  887.  
  888.         return answer
  889.  
  890.     def alter_ctx(self, newUID, bogus_binds = 0):
  891.         answer = self.__class__(self._transport)
  892.  
  893.         answer.set_credentials(self.__username, self.__password)
  894.         answer.set_auth_level(self.__auth_level)
  895.  
  896.         self._max_ctx += 1
  897.         answer.set_ctx_id(self._max_ctx)
  898.         
  899.         answer.bind(newUID, alter = 1, bogus_binds = bogus_binds)
  900.         return answer
  901.  
  902. class DCERPC_RawCall(ImpactPacket.Header):
  903.     def __init__(self, op_num, data = ''):
  904.         self.OP_NUM = op_num
  905.         ImpactPacket.Header.__init__(self)
  906.         self.setData(data)
  907.  
  908.     def setData(self, data):
  909.         self.get_bytes()[:] = array.array('B', data)
  910.  
  911.     def get_header_size(self):
  912.         return len(self.get_bytes())
  913.  
  914.  
  915.